<?php 
namespace app\common\command;

use think\console\Input;
use think\console\Output;
use think\console\command\Make;
use think\console\input\Option;
use think\facade\App;
use think\facade\Env;

class Service extends Make{
    
    protected $type = "Service";
    
    protected $serviceClass;
    
    protected $serviceNamespace;
    
    protected function configure()
    {
        parent::configure();
        $this->setName('make:service')
        ->addOption('api', null, Option::VALUE_NONE, 'Generate an api service class.')
        ->addOption('plain', null, Option::VALUE_NONE, 'Generate an empty service class.')
        ->setDescription('Create a new Service class');
    }
    
    protected function execute(Input $input, Output $output)
    {
        
        $name = trim($input->getArgument('name'));

        $classname = $this->getClassName($name);
        
        $pathname = $this->getPathName($classname);

        if (is_file($pathname)) {
            $output->writeln('<error>' . $this->type . ' already exists!</error>');
            return false;
        }
        if (!is_dir(dirname($pathname))) {
            mkdir(dirname($pathname), 0755, true);
        }
        
        file_put_contents($pathname, $this->buildClass($classname));
        file_put_contents(Env::get('app_path').'provider.php', "\n\r"."bind('".$this->serviceNamespace."\\".$this->serviceClass."','".$this->serviceNamespace."\\impl\\".$this->serviceClass."Impl');",FILE_APPEND);
        
        $this->type = 'ServiceImpl';
        $classname = $this->getClassName($name.'Impl');
        $pathname = $this->getPathName($classname);
        
        if (is_file($pathname)) {
            $output->writeln('<error>' . $this->type . ' already exists!</error>');
            return false;
        }
        
        if (!is_dir(dirname($pathname))) {
            mkdir(dirname($pathname), 0755, true);
        }
        file_put_contents($pathname,str_replace(['{%serviceClass%}', '{%serviceNamespace%}'],[$this->serviceClass,$this->serviceNamespace], $this->buildClass($classname)));
        
   
        $output->writeln('<info> service created successfully </info>');
        
    }
    
    protected function buildClass($name)
    {
        $stub = file_get_contents($this->getStub());
        
        $namespace = trim(implode('\\', array_slice(explode('\\', $name), 0, -1)), '\\');
        $this->serviceNamespace = $namespace;
        $class = str_replace($namespace . '\\', '', $name);
        $this-> serviceClass = $class;
        return str_replace(['{%className%}', '{%namespace%}', '{%app_namespace%}'], [
            $class,
            $namespace,
            App::getNamespace(),
        ], $stub);
    }
    
    protected function getStub()
    {
        $stubPath = __DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR;
        if($this->type == 'Service'){
            
            if ($this->input->getOption('api')) {
                return $stubPath . 'service.stub';
            }
            
            if ($this->input->getOption('plain')) {
                return  $stubPath . 'service.plain.stub';
            }
            
            return $stubPath . 'service.stub';
        }else{
            if ($this->input->getOption('api')) {
                return $stubPath . '\service.impl.stub';
            }
            
            if ($this->input->getOption('plain')) {
                return  $stubPath . 'service.impl.plain.stub';
            }
            
            return $stubPath . 'service.impl.stub';
        }
        
    }
    
    protected function getNamespace($appNamespace, $module)
    {
        return parent::getNamespace($appNamespace, $module) . ( $this->type == 'Service' ? '\service' : '\service\impl' );
    }
    
}
